package com.yanqu.road.server.manger.activity.orewar;

import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.yrank.UserYRank;
import com.yanqu.road.entity.task.args.UnionRiseRankArgs;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.logic.bussiness.player.UserOreWarActivityBussiness;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.pb.orewaractivity.OreWarActivityProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.orewar.OreWarActivityModule;
import com.yanqu.road.server.gameplayer.module.player.OreWarModule;
import com.yanqu.road.server.logic.activity.orewar.OreWarActivityData;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.YRankMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.pb.OreWarActivityPb;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


//盐场争霸活动
public class OreWarActivityMgr extends TempMgr {

    public static final int CONDITION_TYPE_USER = 1;

    public static final int CONDITION_TYPE_UNION = 2;

    private static Logger logger = LogManager.getLogger(OreWarActivityMgr.class.getName());

    private static Map<Integer,ActivityInfo> activityInfoMap = new ConcurrentHashMap<>();

    //activityId type?
    private static Map<Integer, Map<Integer, List<ActivityConditionInfo>>> activityConditionInfoMap = new ConcurrentHashMap<>();

    //activityId mallId
    private static Map<Integer,Map<Integer, MallInfo>> activityMallInfoMap = new ConcurrentHashMap<>();

    //activityId userId type condition
    private static Map<Integer,Map<Long, Map<Integer,List<UserActivityConditionData>>>> userConditionDataMap = new ConcurrentHashMap<>();

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean save() {
        synchronized (userConditionDataMap){
            for(Map<Long, Map<Integer,List<UserActivityConditionData>>> allUserDataMap : userConditionDataMap.values()){
                for(Map<Integer,List<UserActivityConditionData>> userDataMap : allUserDataMap.values()){
                    for (List<UserActivityConditionData> conditionList: userDataMap.values()){
                        for(UserActivityConditionData condition : conditionList){
                            if(condition.getOp() == DataStatus.Insert){
                                UserOreWarActivityBussiness.addUserActivityConditionData(condition);
                            }else if(condition.getOp() == DataStatus.Update){
                                UserOreWarActivityBussiness.updateUserActivityConditionData(condition);
                            }
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean reloadData() {
        return true;
    }

    //通知修改condition
    public static void conditionNotify(long userId,int event,Object object){
        GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
        if(gamePlayer != null){
            gamePlayer.notifyListener(event,object);
        }else{
            for(ActivityInfo activityInfo : activityInfoMap.values()){
                if(event == eGamePlayerEventType.OreWarAcCoinOutPut.getValue() && activityInfo.getChildType() == 1) {//普通盐场
                    conditionNotify(activityInfo.getActivityId(),userId,event,object);
                }else if(event == eGamePlayerEventType.CrossOreWarAcCoinOutPut.getValue() && activityInfo.getChildType() == 2){//跨服盐场
                    conditionNotify(activityInfo.getActivityId(),userId,event,object);
                }
            }
        }
    }

    public static void conditionNotify(Integer activityId,long userId,int event,Object object){
        GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
        if(gamePlayer != null){
            gamePlayer.notifyListener(event,object);
        }else{
            UnionRiseRankArgs args = (UnionRiseRankArgs) object;
            if(null != args) {
                synchronized (userConditionDataMap){
                    List<UserActivityConditionData> tempList = new ArrayList<>();
                    tempList.addAll(userConditionDataMap.get(activityId).get(userId).get(OreWarActivityMgr.CONDITION_TYPE_USER));
                    tempList.addAll(userConditionDataMap.get(activityId).get(userId).get(OreWarActivityMgr.CONDITION_TYPE_UNION));
                    ActivityInfo activityInfo = OreWarActivityMgr.getOpenActivityInfo(activityId);
                    for(UserActivityConditionData data : tempList){
                        if(data.getActivityId() == activityId){
                            if(data.getType() == OreWarActivityMgr.CONDITION_TYPE_UNION){
                                data.setValue(data.getValue().add(args.getValue()));
                                if(!ActivityMgr.activityOverEndTime(activityInfo)){
                                    if (UnionRiseRankArgs.NOTIFY_TYPE_NORMAL == args.getType() || UnionRiseRankArgs.NOTIFY_TYPE_JOIN == args.getType()) {
                                        data.setUnionUid(args.getUnionUid());
                                    } else if (UnionRiseRankArgs.NOTIFY_TYPE_REMOVE == args.getType() || UnionRiseRankArgs.NOTIFY_TYPE_DELETE == args.getType()) {
                                        data.setUnionUid("");
                                    }
                                    if (UnionRiseRankArgs.NOTIFY_TYPE_DELETE == args.getType()) {//解散商会
                                        OreWarActivityRankMgr.removeUnionActivityRank(data.getActivityId(), args.getUnionUid());
                                    }
                                }
                                String unionUid = "";
                                UnionActivityGroupUnion unionData = GameUnionActivityGroupMgr.getUnionData(activityInfo.getActivityId(), userId);
                                if (unionData != null) {
                                    unionUid = unionData.getUnionUid();
                                }
                                YRankMgr.uploadUnionYRank(data, unionUid, UnionRiseRankArgs.NOTIFY_TYPE_NORMAL);

                                OreWarActivityRankMgr.changeUnionActivityValue(data.getActivityId(), args.getUnionUid(), userId, data, args.getType());
                            }else if (data.getType() == OreWarActivityMgr.CONDITION_TYPE_USER) {

                                data.setValue(data.getValue().add(args.getValue()));
                                if (data.getValue().compareTo(BigInteger.ZERO) > 0) {
                                    int groupId = GameUnionActivityGroupMgr.getGroupId(activityInfo.getActivityId(), userId);
                                    if (groupId == UnionActivityGroupHelper.NO_GROUP_ID) {
                                        break;
                                    }
                                    UserBaseInfo baseInfo = UserMgr.getUserBaseInfo(userId, GameServer.getInstance().getServerId());

                                    UserYRank userYRank = new UserYRank();
                                    userYRank.setActivityId(activityInfo.getActivityId());
                                    userYRank.setGroupId(groupId);
                                    userYRank.setIdKey(String.valueOf("1"));
                                    userYRank.setUserId(userId);
                                    userYRank.setUserBaseInfo(baseInfo);
                                    userYRank.setValue(data.getValue());
                                    userYRank.setParam(data.getParam());
                                    userYRank.setUpdateTime(System.currentTimeMillis());
                                    YRankMgr.addUserYRankCache(userYRank);

                                    OreWarActivityRankMgr.changeRank(activityId, UserMgr.getUserInfo(userId), data.getValue());
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    //添加新的活动条件
    public static void addUserActivityConditionData(long userId,UserActivityConditionData userConditionData){
        int activityId = userConditionData.getActivityId();
        synchronized (userConditionDataMap){
            if(!userConditionDataMap.containsKey(activityId)){
                userConditionDataMap.put(activityId,new ConcurrentHashMap<>());
            }
            if(!userConditionDataMap.get(activityId).containsKey(userId)){
                userConditionDataMap.get(activityId).put(userId,new ConcurrentHashMap<>());
            }
            if(!userConditionDataMap.get(activityId).get(userId).containsKey(userConditionData.getType())){
                userConditionDataMap.get(activityId).get(userId).put(userConditionData.getType(),new ArrayList<>());
            }
            userConditionDataMap.get(activityId).get(userId).get(userConditionData.getType()).add(userConditionData);
        }
    }

    //返回用户的condition
    public static Map<Integer, List<UserActivityConditionData>> getUserActivityConditionDataMap(long userId,int activityId){
        if(userConditionDataMap.containsKey(activityId)){
            if(userConditionDataMap.get(activityId).containsKey(userId)){
                return userConditionDataMap.get(activityId).get(userId);
            }
        }
        return null;
    }

    public static void reloadActivityData(Map<Integer, ActivityInfo> selectActivityInfoMap, Map<Integer, Map<Integer, MallInfo>> selectActivityMallInfoMap,
                                          Map<Integer, Map<Integer, List<ActivityConditionInfo>>> selectActivityConditionInfoMap){
        logger.info("reload oreWarActivityMgr start");
        Map<Integer,Map<Integer, List<ActivityConditionInfo>>> inTimeActivityConditionInfoMap = new ConcurrentHashMap<>();
        Map<Integer,ActivityInfo> inTimeActivityMap = new ConcurrentHashMap<>();
        Map<Integer,Map<Integer, MallInfo>> inTimeActivityMallInfoMap = new ConcurrentHashMap<>();

        for(ActivityInfo activityInfo : selectActivityInfoMap.values()){
            if(ActivityMgr.activityInShowTime(activityInfo)){
                if(!inTimeActivityMap.containsKey(activityInfo.getActivityId())){
                    inTimeActivityMap.put(activityInfo.getActivityId(),activityInfo);
                }
                if(null != selectActivityConditionInfoMap.get(activityInfo.getActivityId())) {
                    inTimeActivityConditionInfoMap.put(activityInfo.getActivityId(), selectActivityConditionInfoMap.get(activityInfo.getActivityId()));
                }
                if(null != selectActivityMallInfoMap.get(activityInfo.getActivityId())){
                    inTimeActivityMallInfoMap.put(activityInfo.getActivityId(),selectActivityMallInfoMap.get(activityInfo.getActivityId()));
                }
            }
        }
        Map<Integer,ActivityInfo> oldActivityInfoMap = activityInfoMap;

        for(ActivityInfo activityInfo : inTimeActivityMap.values()){
            if(activityInfo.getChildType() == 1){//本服盐场
                OreWarMgr.loadActivity(activityInfo.getActivityId());
            }else if(activityInfo.getChildType() == 2){//跨服盐场
                OreWarMgr.loadActivity(activityInfo.getActivityId());
            }
            //防止刷新活动的时候用户condition被重新加载，用户身上的condition不能重复加载
            if(oldActivityInfoMap.get(activityInfo.getActivityId()) == null ){
                userConditionDataMap.put(activityInfo.getActivityId(),UserOreWarActivityBussiness.getUserActivityConditionDataMap(activityInfo.getActivityId()));
            }
        }
        //弄到下面来，不然加载数据库会爆炸如果这段时间有人登陆
        activityInfoMap = inTimeActivityMap;
        activityConditionInfoMap = inTimeActivityConditionInfoMap;
        activityMallInfoMap = inTimeActivityMallInfoMap;
        OreWarActivityRankMgr.reloadRank();
        playerReloadActivity();
        OreWarMgr.removeActivity();
        logger.info("reload oreWarActivityMgr end");
    }

    private static void playerReloadActivity() {
        List<GamePlayer> playerList = GamePlayerMgr.getCopyPlayerList();
        playerList.forEach(action -> {
            action.getModule(OreWarActivityModule.class).addNewActivity();
            action.getModule(OreWarActivityModule.class).syncActivity();
            action.getModule(OreWarModule.class).reloadOreWarHp();
            action.getModule(OreWarModule.class).loginSendMsg();
            action.getModule(OreWarModule.class).afterLogin();
        });
    }

    public static ActivityInfo getOpenActivityInfo(int activityId){
        if(!activityInfoMap.containsKey(activityId)){
            return null;
        }
        ActivityInfo activityInfo = activityInfoMap.get(activityId);
        if(ActivityMgr.activityInShowTime(activityInfo) && activityInfo.getActivityId() == activityId){
            return activityInfo;
        }
        return null;
    }

    public static boolean isActivityOver(ActivityInfo activityInfo){
        if(ActivityMgr.activityOver(activityInfo)){
            return true;
        }
        return false;
    }

    public static ActivityInfo getInTimeActivityInfo(int activityId){
        if(!activityInfoMap.containsKey(activityId)){
            return null;
        }
        ActivityInfo activityInfo = activityInfoMap.get(activityId);
        if(ActivityMgr.activityInTime(activityInfo) && activityInfo.getActivityId() == activityId){
            return activityInfo;
        }
        return null;
    }

    public static List<ActivityInfo> getOpenActivityInfoList() {
        List<ActivityInfo> dataList = new ArrayList<>();
        for(ActivityInfo activityInfo : activityInfoMap.values()) {
            if (ActivityMgr.activityInShowTime(activityInfo)) {
                dataList.add(activityInfo);
            }
        }
        return dataList;
    }

    public static Map<Integer,ActivityInfo> getOpenActivityInfoMap() {
        Map<Integer,ActivityInfo> dataMap = new ConcurrentHashMap<>();
        for(ActivityInfo activityInfo : activityInfoMap.values()) {
            if (ActivityMgr.activityInShowTime(activityInfo)) {
                dataMap.put(activityInfo.getActivityId(),activityInfo);
            }
        }
        return dataMap;
    }

    public static MallInfo getMallInfo(int mallId){
        MallInfo mallInfo;
        for(Map<Integer, MallInfo> mallInfoMap : activityMallInfoMap.values()){
            mallInfo = mallInfoMap.get(mallId);
            if(null != mallInfo){
                return mallInfo;
            }
        }
        return null;
    }

    public static List<ActivityConditionInfo> getActivityConditionInfoList(int activityId, int type){
        ActivityInfo openActivityInfo = getOpenActivityInfo(activityId);
        if(null != openActivityInfo) {
            return activityConditionInfoMap.get(activityId).get(type);
        }
        return null;
    }

    public static ActivityConditionInfo getActivityConditionInfoByRank(int activityId, int type, int rank) {
        List<ActivityConditionInfo> dataList = getActivityConditionInfoList(activityId, type);
        if(null != dataList) {
            for (ActivityConditionInfo conditionInfo : dataList) {
                if (rank >= conditionInfo.getParamList().get(0).intValue() && rank <= conditionInfo.getParamList().get(1).intValue()) {
                    return conditionInfo;
                }
            }
        }
        return null;
    }

    public static ActivityConditionInfo getActivityConditionInfo(int activityId, int conditionId) {
        if(activityConditionInfoMap.containsKey(activityId)){
            for (List<ActivityConditionInfo> conditionInfoList : activityConditionInfoMap.get(activityId).values()) {
                for (ActivityConditionInfo conditionInfo : conditionInfoList) {
                    if (conditionId == conditionInfo.getConditionId()) {
                        return conditionInfo;
                    }
                }
            }
        }
        return null;
    }

    public static int getMaxRankByType(int activityId, int type) {
        int maxRank = 0;
        List<ActivityConditionInfo> dataList = getActivityConditionInfoList(activityId, type);
        if(null != dataList) {
            for (ActivityConditionInfo conditionInfo : dataList) {
                if (conditionInfo.getParamList().get(1).intValue() > maxRank) {
                    maxRank = conditionInfo.getParamList().get(1).intValue();
                }
            }
        }
        return maxRank;
    }

    //do-xx 活动数据的生成必须是展示期间领奖期间也给他生成
    /*public static Map<Integer, List<ActivityConditionInfo>> getActivityConditionInfoMap(int activityId) {
        ActivityInfo inTimeActivityInfo = getInTimeActivityInfo(activityId);
        if(null != inTimeActivityInfo) {
            return activityConditionInfoMap;
        }
        return null;
    }*/

    public static Map<Integer, List<ActivityConditionInfo>> getActivityConditionInfoMap(int activityId) {
        ActivityInfo inTimeActivityInfo = getOpenActivityInfo(activityId);
        if(null != inTimeActivityInfo) {
            return activityConditionInfoMap.get(activityId);
        }
        return null;
    }

    public static OreWarActivityProto.OreWarActivityDetailMsg.Builder getOreWarActivityDetailMsg(long userId,Map<Integer,Map<Integer, OreWarActivityData>> activityDataMap, String language){
        return OreWarActivityPb.parseOreWarActivityDetailMsg(userId,activityDataMap, getOpenActivityInfoList(), activityConditionInfoMap, activityMallInfoMap, language);
    }

    public static boolean canChangeUnion(){
        List<ActivityInfo> openActivityInfoList = getOpenActivityInfoList();
        for (ActivityInfo activityInfo:openActivityInfoList){
            if (UnionActivityGroupHelper.needGroup(activityInfo) && ActivityMgr.activityBeforeEndTime(activityInfo)){
                return false;
            }
        }
        return true;
    }
}
